#include "PrecompiledHeaders.h"
#include "UserControlledInputDevice.h"
#include "Ball.h"

/*
 * Constructor
 */
UserControlledInputDevice::UserControlledInputDevice() : InputDevice()
{
    roll = pitch = Ogre::Radian(0);
    ball = NULL;
}

/*
 * Register a ball to control with this device
 */
bool UserControlledInputDevice::registerBall(Ball *b)
{
    if(ball)
    throw new Ogre::Exception(1005, "A Ball is already registered with this device!\n", "UserControlledInputDevice::registerBall");
    ball = b;
    ball->setGravity(Ogre::Vector3::ZERO);
    initialise();
    return true;
}

/*
 * Unregister any ball controlled by this device
 */
void UserControlledInputDevice::unregisterBall()
{
    ball = NULL;
}

/*
 * Set the gravity on the controlled ball based on movements by the device
 */
void UserControlledInputDevice::updateBall(Ogre::Real time)
{
    if(!ball) throw new Ogre::Exception(43242, "No ball registered to this player!", "Player::updateBall");
    Ogre::Quaternion rotation;
    Ogre::Vector3 gravity = original_gravity;
    roll = getX() * -x_factor * sensitivity * invert;
    pitch = getY() * -y_factor * sensitivity * invert;
    if(roll  >  Constants::MAX_ANGLE) roll  =  Constants::MAX_ANGLE;
    if(roll  < -Constants::MAX_ANGLE) roll  = -Constants::MAX_ANGLE;
    if(pitch >  Constants::MAX_ANGLE) pitch =  Constants::MAX_ANGLE;
    if(pitch < -Constants::MAX_ANGLE) pitch = -Constants::MAX_ANGLE;
    if(!camera) throw new Ogre::Exception(1004, "No camera registered with this input device to get yaw from!\n", "UserControlledInputDevice::updateBall");
    rotation = Ogre::Quaternion(pitch, Ogre::Vector3::UNIT_Y.crossProduct(-camera->getDirection()));
    gravity = rotation * gravity;
    rotation = Ogre::Quaternion(roll, Ogre::Vector3::UNIT_Y.crossProduct(camera->getRight()));
    gravity = rotation * gravity;
    ball->setGravity(gravity * speed);
}

/*
 * Reset all values on this device so that it is at the center of its range of movements
 */
void UserControlledInputDevice::reset()
{
    if(!isResettable()) return;
    pitch = roll = Ogre::Radian(0);
    initialise();
}

